package reportd

import (
	"time"

	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
)

var (
	_ ReportAggregateRoot = &reportAggregateRoot{}
)

func initReport(d ddd.Domain, repo ReportRepo) {
	ar := &reportAggregateRoot{}
	ar.Init(ar, d, "report")
	repo.Init(repo, ar, "report")
}

// ReportAggregateRoot 举报的聚合根
type ReportAggregateRoot interface {
	ddd.AggregateRoot
	// 新增举报
	AddReport(ctx ddd.Context, report ReportDesc) (id string, err error)
	// 获取指定举报：根据唯一标识获取举报实体
	GetReport(ctx ddd.Context, id string) (ia *ReportAggregate, err error)
	// 分页获取举报列表：根据唯一标识获取下一页指定数量的举报实体集合
	// total 总数量
	QueryPage(ctx ddd.Context, is ReportSearch, pi common.PageInfo) (npi common.PageResult, result []ReportAggregate, err error)
}

// ReportRepo 举报仓储
type ReportRepo interface {
	ddd.Repository
	// 新增举报
	AddReport(ctx ddd.Context, report ReportDesc) (id string, err error)
	// 获取指定举报：根据唯一标识获取举报实体
	GetReport(ctx ddd.Context, reportid string) (*ReportAggregate, error)
	// 分页获取举报列表：根据唯一标识获取下一页指定数量的举报实体集合
	// total 总数量
	QueryPage(ctx ddd.Context, is ReportSearch, pi common.PageInfo) (npi common.PageResult, result []ReportAggregate, err error)

	// 删除举报 标记删除
	Delete(ctx ddd.Context, reportid string) error

	// 处理举报
	DoResult(ctx ddd.Context, reportid string, reslt ReportResult) error
}

// ReportSearch 查询条件
type ReportSearch struct {
	Key string `json:"key,omitempty"` // 关键字搜索，匹配举报标题
	// TODO 这里设置查询条件
}

// ReportAggregate 举报聚合
type ReportAggregate struct {
	ddd.BaseAggregate
	ReportID     string `json:"report_id"`
	ReportDesc   `json:"desc"`
	ReportResult `json:"result"`
}

// ReportDesc Report描述实例
type ReportDesc struct {
	Content    string    `json:"content"`     // 举报理由
	TargetType int       `json:"target_type"` // 举报类型 1 信息 2 其他
	TargetID   string    `json:"target_id"`   // 举报编号
	Status     int       `json:"status"`      //　举报状态 0 未处理　１　已处理 -1 已删除
	UID        string    `json:"uid"`         // 举报用户
	RepTime    time.Time `json:"rep_time"`    // 举报时间
	Tags       []string  `json:"tags"`        // 举报标签
}

// ReportResult 处理结果
type ReportResult struct {
	Result   string    `json:"result"`    // 处理结果
	ProcUID  string    `json:"proc_uid"`  // 处理用户
	ProcTime time.Time `json:"proc_time"` // 处理时间
}

// Repo 获取聚合根对应的仓储
func (r *ReportAggregate) Repo() ReportRepo {
	return r.Repository().(ReportRepo)
}

// DoResult 处理举报
func (r *ReportAggregate) DoResult(ctx ddd.Context, reslt ReportResult) error {
	err := r.Repo().DoResult(ctx, r.ReportID, reslt)
	if err != nil {
		return err
	}
	r.Trigger(ctx, EvtTypReport, EvtActResult, r.ReportID)
	return err
}

// Delete 删除举报聚合
func (r *ReportAggregate) Delete(ctx ddd.Context) error {
	err := r.Repo().Delete(ctx, r.ReportID)
	if err != nil {
		return err
	}
	r.Trigger(ctx, EvtTypReport, EvtActDelete, r.ReportDesc)
	return err
}

type reportAggregateRoot struct {
	ddd.BaseAggregateRoot
}

func (r *reportAggregateRoot) Repo() ReportRepo {
	return r.Repository().(ReportRepo)
}
func (r *reportAggregateRoot) AddReport(ctx ddd.Context, report ReportDesc) (id string, err error) {
	return r.Repo().AddReport(ctx, report)
}
func (r *reportAggregateRoot) GetReport(ctx ddd.Context, id string) (ia *ReportAggregate, err error) {
	return r.Repo().GetReport(ctx, id)
}

// 分页获取举报列表：根据唯一标识获取下一页指定数量的举报实体集合
// total 总数量
func (r *reportAggregateRoot) QueryPage(ctx ddd.Context, is ReportSearch, pi common.PageInfo) (common.PageResult, []ReportAggregate, error) {
	return r.Repo().QueryPage(ctx, is, pi)
}
